package preprocessor.absorption.extended;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import utils.exception.TypeException;
import domain.tc.TCClashFinder;
import domain.tc.TCNode;
import entities.axiom.AxiomType;
import entities.axiom.ConceptAxiom;
import entities.concept.Concept;

/**
 * @deprecated
 * @author j55wu
 * 
 */
public class AxiomGraph {
	private Set<ConceptAxiom> axs;
	// private boolean initialClash = false;
	public static int called = 0;
	public static long timeSpend = 0;
	public static long graphsize = 0;
	private static Set<TCNode> allnodes;

	public AxiomGraph(Set<ConceptAxiom> axs) {
		this.axs = new HashSet<ConceptAxiom>();
		this.axs.addAll(axs);
		allnodes = new HashSet<TCNode>();
	}

	public void computeRealtedness() throws TypeException {
		// important! must clear all nodes from previous runs
		TCNode.clearAllNodes();
		this.build();
		// visit and compute all nodes
		allnodes.addAll(TCNode.getAllNodes());
		graphsize += TCNode.getAllNodes().size();
		Set<TCNode> testNodes = new HashSet<TCNode>();
		this.computeAllClosures(testNodes);
		return;
	}

	public String getAllComponents() {
		StringBuilder sb = new StringBuilder();
		for (TCNode tc : allnodes) {
			sb.append(this.getRealtedConcept(tc) + "\n");
		}
		return sb.toString();
	}

	private String getRealtedConcept(TCNode tc) {
		List<TCNode> comp = tc.getComponentContent();
		String s = tc.toString() + ": {";
		if (comp == null || comp.size() < 1) {
			s += "";
		} else {
			for (TCNode n : comp) {
				s += n.toString() + ",";
			}
		}
		return s + "}";
	}

	public String getRealtedConcept(Concept c) {
		TCNode tc = TCNode.getConceptAsNode(c);
		return this.getRealtedConcept(tc);
	}

	// for all nodes, only compute closures for those not visited
	private void computeAllClosures(Collection<TCNode> givenNodes) {
		// System.out.printf("[computeTC call %d] on (%d) nodes\n", ++called,
		// givenNodes.size());
		TCClashFinder tc = new TCClashFinder();
		TCNode firstnode = null;
		if (givenNodes.size() > 0) {
			firstnode = givenNodes.iterator().next();
		} else {
			return;
		}
		// do the first pass
		tc.computeTransitiveClosure(firstnode);
		// do TC for those not yet visited
		givenNodes.removeAll(tc.getVisitedNodes());
		if (givenNodes.size() > 0) {
			this.computeAllClosures(givenNodes);
		}
	}

	private void build() throws TypeException {
		// first build initial edges
		for (ConceptAxiom ax : axs) {
			Concept lhs = ax.getLHS();
			AxiomType op = AxiomType.getAxiomType(ax);
			Concept rhs = ax.getRHS();
			TCNode.getConceptAsNode(lhs).addAxiomEdge(op,
					TCNode.getConceptAsNode(rhs));
		}
	}

}
